#include "bitboard.h"
#include "intrin.h"

#include <iostream>

#pragma intrinsic(_bittestandset, _bittestandreset, _bittest, _BitScanForward)

using namespace std;

// ----------
// zjisti zda ve strukture bittboard dany bit nastaven
// bitboard* bb			ukazatel na strutkuru bitboard
// int position			cislo pozice, kterou testuejme
// vraci znak 'x' pokud je bit nastaven jinak vraci '.'
char BitboardUtils::At(bitboard* bb, int position) {
	if(BitboardUtils::TestBit(bb, position)) {
		return 'x';
	}
	else {
		return '.';
	}
}

// ----------
// vytiskne textouvou reprezentaci struktury bitbiard na standartni vystup
// hlavne pro ucely testovani
void BitboardUtils::Print(bitboard bb) {
	for(int i = 0; i < 4; i++) {
		// tiskne liche radky
		cout << ' ';
		cout << BitboardUtils::At(&bb, i*8 + 0);
		cout << ' ';
		cout << BitboardUtils::At(&bb, i*8 + 1);
		cout << ' ';
		cout << BitboardUtils::At(&bb, i*8 + 2);
		cout << ' ';
		cout << BitboardUtils::At(&bb, i*8 + 3);
		cout << endl;

		// tiskne sude radky
		cout << BitboardUtils::At(&bb, i*8 + 4);
		cout << ' ';
		cout << BitboardUtils::At(&bb, i*8 + 5);
		cout << ' ';
		cout << BitboardUtils::At(&bb, i*8 + 6);
		cout << ' ';
		cout << BitboardUtils::At(&bb, i*8 + 7);
		cout << ' ';
		cout << endl;
	}
	cout << endl;
	cout << endl;
}

char BitboardUtils::TestBitAndSet(bitboard* bb, int bit) {
	return _bittestandset((long*)bb, bit);
}

char BitboardUtils::TestBitAndReset(bitboard* bb, int bit) {
	return _bittestandreset((long*)bb, bit);
}

char BitboardUtils::BitScanForward(bitboard bb, int* position) {
	return _BitScanForward((unsigned long*)position, (long)bb);
}

inline char BitboardUtils::TestBit(bitboard *bb, int bit) {
	return _bittest((long*)bb, bit);
}

int BitboardUtils::BitsCount(bitboard bb) {
	int result = 0;
	int pos = 0;
	while(BitboardUtils::BitScanForward(bb, &pos)) {
		result++;
		BitboardUtils::TestBitAndReset(&bb, pos);
	}

	return result;
}